﻿using System.Linq;
using System.Linq.Expressions;
using Hvam.SharePoint.Search.Language;
using Hvam.SharePoint.Search.Language.Visitors;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Hvam.SharePoint.Search.Tests.Internal.Language.Visitors
{
    [TestClass]
    public class PropertyExtractorExpressionVisitorTests
    {
        [TestMethod]
        public void TestExtractEqual()
        {
            // Arrange
            var visitor = new PropertyExtractorExpressionVisitor();
            const string property = "site";
            var expression = Expression.Equal(KeywordQueryExpression.Property("site"), Expression.Constant("coffee"));

            // Act
            var tuple = visitor.Extract(expression, property);

            // Assert
            var properties = tuple.Item2;
            Assert.AreEqual(1, properties.Count);
            Assert.AreEqual("coffee", properties.First());

            AssertExpression.AreEqual(null, tuple.Item1);
        }

        [TestMethod]
        public void TestExtractContains()
        {
            // Arrange
            var visitor = new PropertyExtractorExpressionVisitor();
            const string property = "site";
            var expression = KeywordQueryExpression.Contains(KeywordQueryExpression.Property("site"), Expression.Constant("coffee"));

            // Act
            var tuple = visitor.Extract(expression, property);

            // Assert
            var properties = tuple.Item2;
            Assert.AreEqual(1, properties.Count);
            Assert.AreEqual("coffee", properties.First());

            AssertExpression.AreEqual(null, tuple.Item1);
        }

        [TestMethod]
        public void TestExtractEmpty()
        {
            // Arrange
            var visitor = new PropertyExtractorExpressionVisitor();
            const string property = "site";
            var expression = 
                Expression.Equal(
                    KeywordQueryExpression.Property("property"),
                    Expression.Constant("value"));

            // Act
            var tuple = visitor.Extract(expression, property);

            // Assert
            var properties = tuple.Item2;
            Assert.AreEqual(0, properties.Count);

            AssertExpression.AreEqual(expression, tuple.Item1);
        }

        [TestMethod]
        public void TestExtractAnd()
        {
            // Arrange
            var visitor = new PropertyExtractorExpressionVisitor();
            const string property = "site";
            var expression =
                Expression.And(
                    Expression.Equal(
                        KeywordQueryExpression.Property("Title"),
                        Expression.Constant("water")),
                    Expression.Equal(
                        KeywordQueryExpression.Property("site"),
                        Expression.Constant("coffee"))
                    );

            // Act
            var tuple = visitor.Extract(expression, property);

            // Assert
            var properties = tuple.Item2;
            Assert.AreEqual(1, properties.Count);
            Assert.AreEqual("coffee", properties.First());

            AssertExpression.AreEqual(
                Expression.Equal(
                    KeywordQueryExpression.Property("Title"),
                    Expression.Constant("water")),
                tuple.Item1);
        }
    }
}
